/*
 * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "app_inc.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define APP_DMA_XFER_BUF_COUNT  16U
#define APP_DMA_XFER_CHANNEL_IDX 0U

/*******************************************************************************
 * Variables
 ******************************************************************************/

uint32_t gAppDmaBufferFrom[APP_DMA_XFER_BUF_COUNT];
uint32_t gAppDmaBufferTo[APP_DMA_XFER_BUF_COUNT];
DMA_TransferDescriptor_T gDmaTransferDescriptorStruct[2];

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
void DMA_Configuration(void);


/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Main function
 */
int main(void)
{
    char ch;
    uint32_t i;

    /* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_BootClockRUN();

    /* Initialize debug console. */
    BOARD_InitDebugConsole(); /* Flexcomm0 - UART0, 115200. */

    PRINTF("\r\nDMA Software Trigger Example.\r\n");
    PRINTF("build time: %s, %s\r\n", __TIME__, __DATE__);

    /* Prepare the buffers. */
    for (i = 0U; i < APP_DMA_XFER_BUF_COUNT; i++)
    {
        gAppDmaBufferFrom[i] = i;
        gAppDmaBufferTo[i] = 0U;
    }

    DMA_Configuration();

    while (1)
    {
        ch = GETCHAR();
        PUTCHAR(ch);
    }
}



void DMA_Configuration(void)
{
    DMA_ChannelConfig_T DmaChannelConfigStruct = {0U};
    DMA_TransferConfig_T DmaTransferConfigStruct = {0U};

    uint32_t xfercfg;

    CLOCK_EnableClock(kCLOCK_Dma);

    DMA_Init(DMA0);
    DMA_EnableChannels(DMA0, 1U<<APP_DMA_XFER_CHANNEL_IDX, true);

    DmaChannelConfigStruct.EnablePeripheralRequest = false;
    DmaChannelConfigStruct.EnableHardwareTrigger = false;
    DmaChannelConfigStruct.ChannelPriority = 0U; /* 最高优先级 */
    DMA_SetChannelConfig(DMA0, APP_DMA_XFER_CHANNEL_IDX, &DmaChannelConfigStruct);

    DmaTransferConfigStruct.EnableValidNow = true;
    DmaTransferConfigStruct.EnableReloadNextDescriptor = true; /* Reload the next descriptor when done. */
    DmaTransferConfigStruct.EnableTriggerBySoftwareNow = false;
    DmaTransferConfigStruct.EnableAutoClearTrigger = true; /* Disable the request after the transfer is one. */
    DmaTransferConfigStruct.EnableFlagOnInterruptA = false;
    DmaTransferConfigStruct.EnableFlagOnInterruptB = false;
    DmaTransferConfigStruct.TransferWidth = eDMA_TransferWidth_32b;
    DmaTransferConfigStruct.TransferSourceAddressIncrease = eDMA_TransferAddressIncrease_1xWidth;
    DmaTransferConfigStruct.TransferDestAddressIncrease = eDMA_TransferAddressIncrease_1xWidth;
    DmaTransferConfigStruct.TransferCount = APP_DMA_XFER_BUF_COUNT/2U;
    xfercfg = DMA_CreateTransferConfigWord(&DmaTransferConfigStruct);

    /* Add the first transfer descriptor. */
    gDmaTransferDescriptorStruct[0].TransferConfigWord = xfercfg;
    gDmaTransferDescriptorStruct[0].SourceEndAddrress = (uint32_t)&gAppDmaBufferFrom[APP_DMA_XFER_BUF_COUNT/2U];
    gDmaTransferDescriptorStruct[0].DestEndAddress = (uint32_t)&gAppDmaBufferTo[APP_DMA_XFER_BUF_COUNT/2U];
    gDmaTransferDescriptorStruct[0].LinkToNext = 0U;
    DMA_SetHeadTransferDescriptor(DMA0, APP_DMA_XFER_CHANNEL_IDX, &gDmaTransferDescriptorStruct[0]);

    /* Add the second transfer descriptor, only change the addresses. */
    gDmaTransferDescriptorStruct[1].TransferConfigWord = xfercfg;
    gDmaTransferDescriptorStruct[1].SourceEndAddrress = (uint32_t)&gAppDmaBufferFrom[APP_DMA_XFER_BUF_COUNT];
    gDmaTransferDescriptorStruct[1].DestEndAddress = (uint32_t)&gAppDmaBufferTo[APP_DMA_XFER_BUF_COUNT];
    gDmaTransferDescriptorStruct[1].LinkToNext = 0U;
    DMA_AddTransferDescriptor(DMA0, APP_DMA_XFER_CHANNEL_IDX, &gDmaTransferDescriptorStruct[1]);

    DMA_DoUnlockTriggerBySoftwareCmd(DMA0, 1U << APP_DMA_XFER_CHANNEL_IDX);
    __NOP();
    __NOP();

    DMA_DoUnlockTriggerBySoftwareCmd(DMA0, 1U << APP_DMA_XFER_CHANNEL_IDX);
    __NOP();
    __NOP();


}

/* EOF. */
